﻿using System;
using System.Reactive.Subjects;
using Sbcx.Threading;

namespace Sbcx.Collections.Generic {

    public sealed class ConnectedSubject<T> : ISubject<T>, IConnectableObservable<T> {

        readonly MutableLazy<IDisposable> _connection;
        readonly ISubject<T> _subject;

        public ConnectedSubject (Func<Action, IDisposable> connection, ISubject<T> subject) {
            if (connection == null)
                throw new ArgumentNullException ("connection", "connection is null.");
            if (subject == null)
                throw new ArgumentNullException ("subject", "subject is null.");

            _connection = new MutableLazy<IDisposable> (connection);
            _subject = subject;
        }

        public IDisposable Connect () {
            return _connection.Value;
        }

        public IDisposable Subscribe (IObserver<T> observer) {
            return _subject.Subscribe (observer);
        }

        public void OnCompleted () {
            _subject.OnCompleted ();
        }

        public void OnError (Exception error) {
            _subject.OnError (error);
        }

        public void OnNext (T value) {
            _subject.OnNext (value);
        }
    }
}